package cn.jtool.dig.server.service.impl;

import cn.jtool.dig.server.dao.entity.LogConnect;
import cn.jtool.dig.server.dao.entity.LogTraffic;
import cn.jtool.dig.server.dao.repository.LogConnectRepository;
import cn.jtool.dig.server.dao.repository.LogTrafficRepository;
import cn.jtool.dig.server.service.LogService;
import com.google.common.collect.Lists;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.data.domain.Example;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@Service
public class LogServiceImpl implements LogService {

    @Resource
    private LogTrafficRepository logTrafficRepository;
    @Resource
    private LogConnectRepository logConnectRepository;

    @Override
    public LogConnect saveLogConnect(LogConnect logConnect) {
        if(Objects.nonNull(logConnect.getDisConnectTime())){
            this.saveLogTraffic(
                    LogTraffic.builder()
                            .portMappingId(logConnect.getPortMappingId())
                            .licenseId(logConnect.getLicenseId())
                            .recBytes(logConnect.getRecBytesSegment())
                            .sendBytes(logConnect.getSendBytesSegment())
                            .build()
            );
        }
        return this.logConnectRepository.saveAndFlush(logConnect);
    }

    @Override
    public void saveLogTraffic(LogTraffic logTraffic) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHH");
        LogTraffic logTrafficDB = this.logTrafficRepository.findOne(
                Example.of(
                        LogTraffic.builder()
                                .portMappingId(logTraffic.getPortMappingId())
                                .timeTag(sdf.format(new Date()))
                                .build()
                )
        ).orElse(null);
        if(Objects.isNull(logTrafficDB)){
            logTraffic.setTimeTag(sdf.format(new Date()));
            logTrafficDB = logTraffic;
        }else{
            logTrafficDB.setRecBytes(logTraffic.getRecBytes() + logTrafficDB.getRecBytes());
            logTrafficDB.setSendBytes(logTraffic.getSendBytes() + logTrafficDB.getSendBytes());
        }
        this.logTrafficRepository.saveAndFlush(logTrafficDB);
    }

    @Override
    public void saveLogTraffic(List<LogTraffic> logTraffics) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHH");
        List<LogTraffic> trafficList = this.logTrafficRepository.findAll(
                Example.of(LogTraffic.builder().timeTag(sdf.format(new Date())).build())
        );
        logTraffics.forEach(logTraffic -> {
            logTraffic.setTimeTag(sdf.format(new Date()));
        });
        List<LogTraffic> saveList = logTraffics;
        if(CollectionUtils.isNotEmpty(trafficList)){
            Map<Integer, LogTraffic> trafficMap = trafficList.stream().collect(Collectors.toMap(LogTraffic::getPortMappingId, logTraffic -> logTraffic));
            List<LogTraffic> finalSaveList = Lists.newArrayList();
            logTraffics.forEach(logTraffic -> {
                LogTraffic trafficDB = trafficMap.get(logTraffic.getPortMappingId());
                if(Objects.isNull(trafficDB)){
                    finalSaveList.add(logTraffic);
                }else{
                    trafficDB.setRecBytes(logTraffic.getRecBytes() + trafficDB.getRecBytes());
                    trafficDB.setSendBytes(logTraffic.getSendBytes() + trafficDB.getSendBytes());
                    finalSaveList.add(trafficDB);
                }
            });
            saveList = finalSaveList;
        }
        this.logTrafficRepository.saveAllAndFlush(saveList);
    }
}
